package com.utf999.qiangmanger.service.impl;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.utf999.qiangmanger.dao.iface.IOrderInfoCommodityDAO;
import com.utf999.qiangmanger.dao.iface.IOrderInfoDAO;
import com.utf999.qiangmanger.entity.PageEntity;
import com.utf999.qiangmanger.entity.orm.CommodityEntity;
import com.utf999.qiangmanger.entity.orm.OrderInfoCommodityEntity;
import com.utf999.qiangmanger.entity.orm.OrderInfoEntity;
import com.utf999.qiangmanger.entity.orm.OrderTypeDefineEntity;
import com.utf999.qiangmanger.entity.orm.OrderTypeEntity;
import com.utf999.qiangmanger.entity.orm.StoreUserEntity;
import com.utf999.qiangmanger.entity.orm.StorefrontEntity;
import com.utf999.qiangmanger.entity.report.UserPerformance;
import com.utf999.qiangmanger.exception.BizException;
import com.utf999.qiangmanger.exception.ResponseCode;
import com.utf999.qiangmanger.service.AbstractService;
import com.utf999.qiangmanger.service.iface.IOrderInfoService;
import com.utf999.qiangmanger.service.iface.IOrderTypeDefineService;
import com.utf999.qiangmanger.service.iface.IOrderTypeService;
import com.utf999.qiangmanger.service.iface.IStoreUserService;
import com.utf999.qiangmanger.service.iface.IStorefrontService;

/**
 * @author yinwenjie
 */
@Component("OrderInfoServiceImpl")
public class OrderInfoServiceImpl extends AbstractService<OrderInfoEntity, IOrderInfoDAO> implements IOrderInfoService {

	/**
	 * 
	 */
	@Autowired
	private IOrderInfoDAO orderInfoDAO;
	
	/**
	 * 
	 */
	//TODO 不应该在这里的DAO。为了偷懒
	@Autowired
	private IOrderInfoCommodityDAO orderInfoCommodityDAO;
	
	@Autowired
	private IOrderTypeService orderTypeService;
	
	@Autowired
	private IOrderTypeDefineService orderTypeDefineService;
	
	@Autowired
	private IStorefrontService storefrontService;
	
	@Autowired
	private IStoreUserService storeUserService;
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.AbstractService#getBaseDAO()
	 */
	@Override
	protected IOrderInfoDAO getBaseDAO() {
		return this.orderInfoDAO;
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#createOrder(java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.String[], java.lang.String, java.lang.String[], java.lang.Integer[], java.lang.String)
	 */
	@Override
	public void createOrder(String storeid, String roomNo,
			String orderTypeCode, Integer duration, Integer integral,
			Integer fenpeiType, String[] usergroupid, String zhipaiUserid,
			String[] commodityid, Integer[] commodityNumber, String remark)
			throws BizException {
		/*
		 * 1、首先进行传入各参数的判断。需要注意的是，根据分配方式、工单类型的不同。传入参数的判断也是有区别的
		 * 2、先进行工单基本信息的插入操作
		 * 3、根据分配方式的不同、决定是否映射用户组信息
		 * 4、根据工单类型的不同，决定是否映射商品信息
		 * */
		//==============================1
		if(StringUtils.isEmpty(storeid) || StringUtils.isEmpty(roomNo)
			|| StringUtils.isEmpty(orderTypeCode) || duration == null
			|| integral == null || fenpeiType == null) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E403);
		}
		//如果是抢单方式，只有要有一个用户组信息
		if(fenpeiType == 1 && (usergroupid == null || usergroupid.length == 0)) {
			throw new BizException("您设置的抢单模式，但是没有选定任何用户组。", ResponseCode.E402);
		}
		//如果是指派方式，就必须有指定的用户id
		if(fenpeiType == 2 && StringUtils.isEmpty(zhipaiUserid)) {
			throw new BizException("您设置的指派模式，但是没有选定服务员。", ResponseCode.E402);
		}
		//如果是消费单，则至少有一个商品信息，且commodityid和commodityNumber两个数组的元素个数一致
		if(StringUtils.equals(orderTypeCode, "0001") && 
			(commodityid == null || commodityid.length == 0
			|| commodityNumber == null || commodityNumber.length == 0
			|| commodityid.length != commodityNumber.length)) {
			throw new BizException("这是一张消费服务工单，请至少指定一个商品信息和商品数量。并且商品信息和数量要对应。", ResponseCode.E402);
			
		} else if(!StringUtils.equals(orderTypeCode, "0001") && StringUtils.isEmpty(remark)) {
			throw new BizException("这张服务工单没有进行任务说明。", ResponseCode.E402);
		}
		
		//查询出所必须的管理信息
		//查询对应的公司
		StorefrontEntity storeFront = (StorefrontEntity)this.storefrontService.getEntity(storeid);
		String companyid = storeFront.getCompany().getUid();
		//查询对应的工单类型
		OrderTypeEntity orderType = this.orderTypeService.queryOrderTypeByCode(companyid, orderTypeCode);
		
		//==============================2
		OrderInfoEntity orderinfo = new OrderInfoEntity();
		orderinfo.setCompany(storeFront.getCompany());
		orderinfo.setStorefront(storeFront);
		orderinfo.setCreateTime(new Date());
		orderinfo.setFilingTime(null);
		orderinfo.setDuration(duration);
		orderinfo.setIntegral(integral);
		orderinfo.setOrderType(orderType);
		orderinfo.setRoomNo(roomNo);
		//分配方式
		orderinfo.setOrderMode(fenpeiType);
		//工单方式为“指派”时，需要绑定人员
		if(fenpeiType == 2) {
			StoreUserEntity storeUser = (StoreUserEntity)this.storeUserService.getEntity(zhipaiUserid);
			if(storeUser == null) {
				throw new BizException("没有找到指派的服务员，请检查!", ResponseCode.E402);
			}
			orderinfo.setWaiter(storeUser);
			//已派单
			orderinfo.setOrderStatus(2);
			//还要设置指派时间
			orderinfo.setAppointeTime(new Date());
		} else {
			orderinfo.setOrderStatus(1);
		}
		//肯定超市都还没有完成商品配送
		orderinfo.setPickingStatus(0);
		
		//如果当前工单不为“消费单”，则任务说明必须有
		if(!StringUtils.equals(orderTypeCode, "0001")) {
			try {
				orderinfo.setRemark(new String(remark.getBytes("ISO-8859-1"),"utf-8"));
			} catch (UnsupportedEncodingException e) {
				throw new BizException(e.getMessage(), ResponseCode.E501);
			}
		}
		orderinfo.setServiceOverTime(null);
		orderinfo.setTotalAmount(0.0f);
		this.orderInfoDAO.insertAndRefresh(orderinfo);
		
		//==============================3
		if(fenpeiType == 1) {
			this.orderInfoDAO.appendOrderInfoGroupMapping(orderinfo.getUid(), usergroupid);
		}
		
		//==============================4
		if(StringUtils.equals(orderTypeCode, "0001")) {
			for (Integer index = 0 ; commodityid != null && index < commodityid.length ; index++) {
				String commodityidItem = commodityid[index];
				Integer commodityNumberItem = commodityNumber[index];
				this.orderInfoCommodityDAO.appendOrderInfoCommodity(orderinfo.getUid(), commodityidItem, commodityNumberItem);
			}
		}
	}

	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#appendOrderInfoGroupMapping(java.lang.String, java.lang.String[])
	 */
	@Override
	public void appendOrderInfoGroupMapping(String orderinfoID, String[] groupid) throws BizException {
		if(StringUtils.isEmpty(orderinfoID)
			|| groupid == null || groupid.length == 0) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		this.orderInfoDAO.appendOrderInfoGroupMapping(orderinfoID, groupid);
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#updatePickingStatus(java.lang.String, java.lang.Float)
	 */
	@Override
	public void updatePickingStatus(String orderinfoid, Float totalAmount) throws BizException {
		if(StringUtils.isEmpty(orderinfoid) || totalAmount == null) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		this.orderInfoDAO.updatePickingStatus(orderinfoid, totalAmount);
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#saveOrderinfoAccount(java.lang.String, java.lang.String, java.lang.Integer, java.lang.Float)
	 */
	@Override
	public void saveOrderinfoAccount(String orderinfoid, String adminuserid, Integer realIntegral, Float realTotalAmount) throws BizException {
		if(StringUtils.isEmpty(orderinfoid) || StringUtils.isEmpty(adminuserid)
			|| realIntegral == null) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		if(realTotalAmount == null) {
			realTotalAmount = 0.0f;
		}
		
		this.orderInfoDAO.saveOrderinfoAccount(orderinfoid, adminuserid, realIntegral, realTotalAmount);
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#saveOrderinfoAccounts(java.lang.String[], java.lang.String, java.lang.Integer[])
	 */
	@Override
	public void saveOrderinfoAccounts(String[] orderinfoids, String adminuserid, Integer[] realIntegrals) throws BizException {
		if(StringUtils.isEmpty(adminuserid) 
			|| realIntegrals == null || realIntegrals.length == 0
			|| orderinfoids == null || orderinfoids.length == 0
			|| realIntegrals.length != orderinfoids.length) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		for(int index = 0 ; index < orderinfoids.length ; index++) {
			String orderinfoid = orderinfoids[index];
			Integer realIntegral = realIntegrals[index];
			
			this.orderInfoDAO.saveOrderinfoAccount(orderinfoid, adminuserid, realIntegral , 0.0f);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#withdrawOrderInfo(java.lang.String)
	 */
	@Override
	public void withdrawOrderInfo(String orderinfoid) throws BizException {
		if(StringUtils.isEmpty(orderinfoid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		OrderInfoEntity orderInfo = (OrderInfoEntity)this.getEntity(orderinfoid);
		if(orderInfo == null) {
			throw new BizException("没有查找到对应的工单信息！", ResponseCode.E403);
		}
		Integer orderStatus = orderInfo.getOrderStatus();
		if(orderStatus != 1 && orderStatus != 2) {
			throw new BizException("只有“抢单中”、“已派单”状态的工单，能被撤回", ResponseCode.E501);
		}
		
		orderInfo.setOrderStatus(0);
		this.update(orderInfo);
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#queryPickingOrder(java.lang.String)
	 */
	@Override
	public List<OrderInfoEntity> queryPickingOrder(String storefrontid) throws BizException {
		if(StringUtils.isEmpty(storefrontid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		return this.orderInfoDAO.queryPickingOrder(storefrontid);
	}

	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#queryTaskOrder(java.lang.String, java.lang.Integer, java.lang.Integer, java.lang.String, java.lang.String)
	 */
	@Override
	public List<OrderInfoEntity> queryTaskOrder(String storefrontid, Integer orderMode, Integer orderStatus, String waiterCode, String roomNo) throws BizException {
		if(StringUtils.isEmpty(storefrontid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		return this.orderInfoDAO.queryTaskOrder(storefrontid, orderMode, orderStatus, waiterCode, roomNo);
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#queryAccountOrder(java.lang.String, java.lang.Integer, java.lang.String, java.lang.String)
	 */
	@Override
	public JSONArray queryAccountOrders(String storefrontid, Integer orderMode, String waiterCode, String roomNo) throws BizException {
		if(StringUtils.isEmpty(storefrontid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		/*
		 * 核算列表和待办列表最大的区别就是：
		 * 核算列表除了按条件查询“带核算”信息以外，还会按照设定的奖惩信息进行最后的积分计算。
		 * 所以处理过程为：
		 * 1、首先按照条件查询带核算列表。
		 * 2、然后查询这个公司下，各工单设定的奖惩信息。（注意，只查询一次就行了，放到内存中以便下次使用）
		 * 3、然后计算每一条工单的“办理时长”，按照办理时长的特点和这个工单类型的积分奖惩情况，进行计算
		 * 4、计算后，再重新组装JSON返回信息。返回给调用者
		 * */
		//1、==============
		List<OrderInfoEntity> orderinfos = this.orderInfoDAO.queryAccountOrders(storefrontid, orderMode, waiterCode, roomNo);
		if(orderinfos == null || orderinfos.size() == 0) {
			return null;
		}
		
		//4、==============
		//已经查询得到的奖惩信息，存放在这里
		HashMap<String, List<OrderTypeDefineEntity>> orderTypeDefinesMapping = new HashMap<String, List<OrderTypeDefineEntity>>();
		//返回的结果放在这里
		JSONArray returnOrderinfoArray = new JSONArray();
		for (OrderInfoEntity orderInfo : orderinfos) {
			JSONObject returnOrderinfo = new JSONObject();
			returnOrderinfo.put("uid", orderInfo.getUid());
			//房间号
			returnOrderinfo.put("roomNo", orderInfo.getRoomNo());
			//状态、模式
			returnOrderinfo.put("orderMode", orderInfo.getOrderMode());
			returnOrderinfo.put("orderStatus", orderInfo.getOrderStatus());
			//订单类型
			OrderTypeEntity orderType = orderInfo.getOrderType();
			returnOrderinfo.put("orderTypeName", orderType.getOrderTypeName());
			returnOrderinfo.put("orderTypeCode", orderType.getOrderCode());
			
			//2、==================
			//奖惩信息查询,如果条件成成立，说明需要在数据库中查询，并存储到orderTypeDefinesMapping中
			List<OrderTypeDefineEntity> defines = null;
			if(orderTypeDefinesMapping.get(orderType.getUid()) == null) {
				defines = this.orderTypeDefineService.queryOrderTypeDefine(orderType.getUid());
				//从数据库查询查来的信息，要存储的临时空间
				if(defines == null) {
					defines = new LinkedList<OrderTypeDefineEntity>();
					orderTypeDefinesMapping.put(orderType.getUid(), defines);
				} else {
					orderTypeDefinesMapping.put(orderType.getUid(), defines);
				}
			} else {
				defines = orderTypeDefinesMapping.get(orderType.getUid());
			}
			
			//订单办理人
			StoreUserEntity waiter = orderInfo.getWaiter();
			if(waiter == null) {
				returnOrderinfo.put("realName", null);
				returnOrderinfo.put("workNumber", null);
			} else {
				returnOrderinfo.put("realName", waiter.getRealName());
				returnOrderinfo.put("workNumber", waiter.getWorkNumber());
			}
			//各种时间
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			returnOrderinfo.put("createTime", simpleDateFormat.format(orderInfo.getCreateTime()));
			Date appointeTime = orderInfo.getAppointeTime();
			returnOrderinfo.put("appointeTime", simpleDateFormat.format(appointeTime));
			Date serviceOverTime = orderInfo.getServiceOverTime();
			returnOrderinfo.put("serviceOverTime", simpleDateFormat.format(serviceOverTime));
			//标准耗时、积分、应付金额
			Integer duration = orderInfo.getDuration();
			returnOrderinfo.put("duration", duration);
			Integer integral = orderInfo.getIntegral();
			returnOrderinfo.put("integral", integral);
			Float totalAmount = orderInfo.getTotalAmount();
			if(totalAmount == null || totalAmount == 0f) {
				returnOrderinfo.put("totalAmount", "0.00");
			} else {
				DecimalFormat df = new DecimalFormat("#.00");
				returnOrderinfo.put("totalAmount", df.format(totalAmount));
			}
			
			
			//3、==============计算时间
			this.account(returnOrderinfo, defines, duration, integral, serviceOverTime, appointeTime);
			returnOrderinfoArray.add(returnOrderinfo);
		}
		
		return returnOrderinfoArray;
	}
	
	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#queryAccountOrders(java.lang.String)
	 */
	@Override
	public JSONObject queryAccountOrder(String orderinfoid) throws BizException {
		/*
		 * 这个方法就是
		 * public JSONArray queryAccountOrders(String storefrontid, Integer orderMode, String waiterCode, String roomNo) throws BizException
		 * 方法的简化。
		 * 具体过程请参见以上方法
		 * */
		//1、==============
		OrderInfoEntity orderInfo = this.orderInfoDAO.queryAccountOrder(orderinfoid);
		if(orderInfo == null) {
			return null;
		}
		
		//4、==============
		//返回的结果放在这里
		JSONObject returnOrderinfo = new JSONObject();
		returnOrderinfo.put("uid", orderInfo.getUid());
		//房间号
		returnOrderinfo.put("roomNo", orderInfo.getRoomNo());
		//状态、模式
		returnOrderinfo.put("orderMode", orderInfo.getOrderMode());
		returnOrderinfo.put("orderStatus", orderInfo.getOrderStatus());
		//订单类型
		OrderTypeEntity orderType = orderInfo.getOrderType();
		returnOrderinfo.put("orderTypeName", orderType.getOrderTypeName());
		String orderTypeCode = orderType.getOrderCode();
		returnOrderinfo.put("orderTypeCode", orderTypeCode);
		
		//2、==================
		List<OrderTypeDefineEntity> defines = this.orderTypeDefineService.queryOrderTypeDefine(orderType.getUid());
		
		//订单办理人
		StoreUserEntity waiter = orderInfo.getWaiter();
		if(waiter == null) {
			returnOrderinfo.put("realName", null);
			returnOrderinfo.put("workNumber", null);
		} else {
			returnOrderinfo.put("realName", waiter.getRealName());
			returnOrderinfo.put("workNumber", waiter.getWorkNumber());
		}
		//各种时间
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		returnOrderinfo.put("createTime", simpleDateFormat.format(orderInfo.getCreateTime()));
		Date appointeTime = orderInfo.getAppointeTime();
		returnOrderinfo.put("appointeTime", simpleDateFormat.format(appointeTime));
		Date serviceOverTime = orderInfo.getServiceOverTime();
		returnOrderinfo.put("serviceOverTime", simpleDateFormat.format(serviceOverTime));
		//标准耗时、积分、应付金额
		Integer duration = orderInfo.getDuration();
		returnOrderinfo.put("duration", duration);
		Integer integral = orderInfo.getIntegral();
		returnOrderinfo.put("integral", integral);
		Float totalAmount = orderInfo.getTotalAmount();
		if(totalAmount == null || totalAmount == 0f) {
			returnOrderinfo.put("totalAmount", "0.00");
		} else {
			DecimalFormat df = new DecimalFormat("#.00");
			returnOrderinfo.put("totalAmount", df.format(totalAmount));
		}
		//可能的商品信息
		if(orderTypeCode.equals("0001")) {
			JSONArray commoditysMaps = new JSONArray();
			Set<OrderInfoCommodityEntity> commoditysMapping = orderInfo.getCommoditys();
			for (OrderInfoCommodityEntity orderInfoCommodity : commoditysMapping) {
				CommodityEntity commodity = orderInfoCommodity.getCommodify();
				Integer commodifyNumber = orderInfoCommodity.getCommodifyNumber();
				
				JSONObject commodityObject = new JSONObject();
				commodityObject.put("commodityName", commodity.getCommodityName());
				commodityObject.put("commodifyNumber", commodifyNumber);
				commodityObject.put("sortName", commodity.getSortName());
				commoditysMaps.add(commodityObject);
			}
			returnOrderinfo.put("commoditys", commoditysMaps);
		} else {
			returnOrderinfo.put("commoditys", null);
		}
		//可能的任务说明
		returnOrderinfo.put("remark", orderInfo.getRemark());
		
		//3、==============计算时间
		this.account(returnOrderinfo, defines, duration, integral, serviceOverTime, appointeTime);
		
		//返回
		return returnOrderinfo;
	}
	
	/**
	 * 这个私有方法用于计算单张工单的实际耗时、实际积分
	 * @param returnOrderinfo
	 * @param duration 标准耗时
	 * @param integral 标注积分
	 * @param serviceOverTime 服务完成时间
	 * @param appointeTime 服务指派时间
	 */
	private void account(JSONObject returnOrderinfo , List<OrderTypeDefineEntity> defines , Integer duration , Integer integral , Date serviceOverTime , Date appointeTime) {
		//真实的耗时情况
		Integer realDuration = new Long((serviceOverTime.getTime() - appointeTime.getTime()) / 1000).intValue();
		//这是一种数据错误的情况，需要表示异常
		if(realDuration <= 0) {
			returnOrderinfo.put("realIntegralRemark", "错误数据");
			returnOrderinfo.put("realIntegral", integral);
			returnOrderinfo.put("realDuration", 0);
			return;
		} else {
			returnOrderinfo.put("realDuration", realDuration);
		}
		//标准时间与真实时间的差值(真实耗时 - 标准耗时)
		Integer diffDuration = realDuration - duration;
		
		//开始进行积分计算
		Integer realIntegral = null;
		if(defines == null || defines.size() == 0 || diffDuration == 0) {
			returnOrderinfo.put("realIntegralRemark", "默认积分");
			realIntegral = integral;
		} else if (diffDuration < 0) {
			/*
			 * 在耗时小于标准耗时的情况下，两个边界条件是：
			 * 1、如果耗时比最小耗时都还要小，则按照最小耗时设定的奖励条件来奖励
			 * 2、如果耗时比最小节约时间都还要大（例如耗时是99秒，但是设定的最小节约时间在95秒），那么就不奖励
			 * */
			Integer previousDurationChange = null;
			for (int index = 0 ; defines != null && index < defines.size() ; index++) {
				OrderTypeDefineEntity define = defines.get(index);
				if(define.getDurationChange() > 0) {
					returnOrderinfo.put("realIntegralRemark", "节约了时间，但不进行奖励");
					realIntegral = integral;
					break;
				}
				
				//如果一下任何一种条件成立，说明实际耗时在这个奖励区间
				if((index == 0 && duration + define.getDurationChange() >= realDuration)
					|| (index != 0 && duration + previousDurationChange < realDuration 
					&& duration + define.getDurationChange() >= realDuration)) {
					realIntegral = new BigDecimal(100 + define.getIntegralChange()).divide(new BigDecimal(100)).multiply(new BigDecimal(integral)).intValue();
					returnOrderinfo.put("realIntegralRemark", "节约时间：" + define.getDurationChange() + "的奖励");
					break;
				} else {
					previousDurationChange = define.getDurationChange();
				}
				
				//如果进行到这里，说明虽然节约了时间，但是不构成最小奖励条件
				//(实际上有了上面的判断，有没有这个判断中后半部分的判断，都无所谓了)
				if(index + 1 == defines.size() && duration + define.getDurationChange() < realDuration) {
					returnOrderinfo.put("realIntegralRemark", "节约了时间，但不进行奖励");
					realIntegral = integral;
				}
			}
		} else if (diffDuration > 0) {
			/*
			 * 在耗时大于标准耗时的情况下，两个边界条件是：
			 * 1、如果耗时比最大惩罚耗时都还要大，那么按照最大惩罚耗时进行惩罚
			 * 2、如果耗时比最小惩罚耗时要小（例如耗时是101秒，但设定的最小需超过105秒才会惩罚），那么就不惩罚
			 * */
			Integer previousDurationChange = 0;
			for (int index = 0 ; defines != null && index < defines.size() ; index++) {
				OrderTypeDefineEntity define = defines.get(index);
				if(define.getDurationChange() < 0) {
					continue;
				}
				
				//如果条件成立，说明虽然超时了，但是也不进行惩罚
				if(previousDurationChange == 0 &&  duration + define.getDurationChange() > realDuration) {
					realIntegral = integral;
					returnOrderinfo.put("realIntegralRemark", "超时，但不进行惩罚");
					break;
				}
				
				//如果条件成立，说明实际耗时在这个惩罚区间
				if((index + 1 != defines.size() && duration + previousDurationChange < realDuration
					&& duration + define.getDurationChange() >= realDuration)
					|| (index + 1 == defines.size() && duration + define.getDurationChange() <= realDuration)) {
					realIntegral = new BigDecimal(100 + define.getIntegralChange()).divide(new BigDecimal(100)).multiply(new BigDecimal(integral)).intValue();
					returnOrderinfo.put("realIntegralRemark", "超时" + define.getDurationChange() + "的惩罚");
					break;
				}
			}
		} else {
			realIntegral = integral;
		}
		returnOrderinfo.put("realIntegral", realIntegral);
	}

	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#queryOrderinfoDetails(java.lang.String)
	 */
	@Override
	public OrderInfoEntity queryOrderinfoDetails(String orderinfoid) throws BizException {
		if(StringUtils.isEmpty(orderinfoid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		
		return this.orderInfoDAO.queryOrderinfoDetails(orderinfoid);
	}

	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#reportOrderInfo(java.lang.String, java.lang.String, java.lang.Integer, java.lang.String, java.lang.String, java.util.Date, java.util.Date, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public PageEntity reportOrderInfo(String companyid, String storefrontid,
			Integer orderMode, String workNumber, String roomNo,
			String beginFilingTime, String endFilingTime, Integer pageNum,
			Integer maxrow) throws BizException {
		/*
		 * 注意，companyid和storefrontid肯定有一个要传入。否则报错
		 * */
		if(StringUtils.isEmpty(companyid) && StringUtils.isEmpty(storefrontid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		//日期范围必须有，且时间跨度不超过一年
		if(StringUtils.isEmpty(beginFilingTime) || StringUtils.isEmpty(endFilingTime)) {
			throw new BizException("必须要指定报表的时间范围。", ResponseCode.E403);
		}
		//进行时间转化
		SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date beginFiling = null;
		Date endFiling = null;
		try {
			beginFiling = dataFormat.parse(beginFilingTime + " 00:00:00");
			endFiling = dataFormat.parse(endFilingTime + " 23:59:59");
		} catch(Exception e) {
			throw new BizException(e.getMessage(), ResponseCode.E501);
		}
		
		return this.orderInfoDAO.reportOrderInfo(companyid, storefrontid, orderMode, workNumber, roomNo, beginFiling, endFiling, pageNum, maxrow);
	}

	/* (non-Javadoc)
	 * @see com.utf999.qiangmanger.service.iface.IOrderInfoService#reportTotalGroupbyUserid(java.lang.String, java.lang.String, java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public PageEntity reportTotalGroupbyUserid(String companyid,
			String storefrontid, Integer orderMode, String workNumber,
			String roomNo, String beginFilingTime, String endFilingTime,
			Integer pageNum, Integer maxrow) throws BizException {
		
		/*
		 * 注意，companyid和storefrontid肯定有一个要传入。否则报错
		 * */
		if(StringUtils.isEmpty(companyid) && StringUtils.isEmpty(storefrontid)) {
			throw new BizException("错误的参数信息，请检查！", ResponseCode.E404);
		}
		//日期范围必须有，且时间跨度不超过一年
		if(StringUtils.isEmpty(beginFilingTime) || StringUtils.isEmpty(endFilingTime)) {
			throw new BizException("必须要指定报表的时间范围。", ResponseCode.E403);
		}
		//进行时间转化
		SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date beginFiling = null;
		Date endFiling = null;
		try {
			beginFiling = dataFormat.parse(beginFilingTime + " 00:00:00");
			endFiling = dataFormat.parse(endFilingTime + " 23:59:59");
		} catch(Exception e) {
			throw new BizException(e.getMessage(), ResponseCode.E501);
		}
		
		//由于底层是SQL的查询，所以这里比对json信息进行自行构造
		PageEntity queryPageEntity = this.orderInfoDAO.reportTotalGroupbyUserid(companyid, storefrontid, orderMode, workNumber, roomNo, beginFiling, endFiling, pageNum, maxrow);
		List<Object[]> resultsByObjects = queryPageEntity.getResultsByObject();
		if(resultsByObjects == null || resultsByObjects.size() == 0) {
			return null;
		}
		
		List<UserPerformance> performances = new ArrayList<UserPerformance>();
		for (Object[] objects : resultsByObjects) {
			UserPerformance performance = new UserPerformance();
			//waterid
			performance.setWaiter(objects[0].toString());
			//realTotalAmount
			Double realTotalAmount = (Double)objects[1];
			BigDecimal decimalFormat = new BigDecimal(realTotalAmount).setScale(2, RoundingMode.HALF_UP);
			performance.setRealTotalAmount(decimalFormat.floatValue());
			//realTotalIntegral
			performance.setRealTotalIntegral(((BigDecimal)objects[2]).intValue());
			//userName
			performance.setUserName(objects[3].toString());
			//realName
			performance.setRealName(objects[4].toString());
			//workNumber
			performance.setWorkNumber(objects[5].toString());
			//storeName
			performance.setStoreName(objects[6].toString());
			
			performances.add(performance);
		}
		
		queryPageEntity.setResults(performances);
		queryPageEntity.setResultsByObject(null);
		return queryPageEntity;
	}
}
